package org.bwf.study.servcie.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.bwf.obj.bo.CinemaQueryListBO;
import org.bwf.obj.dto.CinemaQueryListDTO;
import org.bwf.obj.dto.CinemaQueryModelDTO;
import org.bwf.study.aop.RedisAnnotation;
import org.bwf.study.mapper.*;
import org.bwf.study.model.*;
import org.bwf.study.servcie.CinemaService;
import org.bwf.study.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CinemaServiceImpl implements CinemaService {

    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private SpecialHallMapper specialHallMapper;
    @Autowired
    private CinemaMapper cinemaMapper;
    @Autowired
    private CinemaFilmRelMapper cinemaFilmRelMapper;
    @Autowired
    private FilmMapper filmMapper;
    @Autowired
    private WatchTimesMapper watchTimesMapper;

    @Override
    @RedisAnnotation(Duration = 900)
    public CinemaQueryListDTO CinemaQueryList(CinemaQueryListBO cinemaQueryListBO) {
        CinemaQueryListDTO cinemaQueryListDTO = new CinemaQueryListDTO();

        // 加载全部的Brand信息
        cinemaQueryListDTO.setBrands(brandMapper.selectList(null));
        // 加载全部的SpecialHall信息
        cinemaQueryListDTO.setSpecialHalls(specialHallMapper.selectList(null));

        // 查询参数处理
        LambdaQueryWrapper<Cinema> cinemaLambdaQueryWrapper = Wrappers.lambdaQuery();

        if(cinemaQueryListBO.getBrandId() != null)
            cinemaLambdaQueryWrapper.eq(Cinema::getBrandId, cinemaQueryListBO.getBrandId());
        if(cinemaQueryListBO.getSpecialId() != null)
            cinemaLambdaQueryWrapper.like(Cinema::getCmaHallsQuery, cinemaQueryListBO.getSpecialId());
        if(cinemaQueryListBO.getService() != null && !"".equals(cinemaQueryListBO.getService()))
            cinemaLambdaQueryWrapper.like(Cinema::getCmaServiceQuery, cinemaQueryListBO.getService());

        // 排序处理
        if(cinemaQueryListBO.getOrderCol() != null && !"".equals(cinemaQueryListBO.getOrderCol()))
            cinemaLambdaQueryWrapper.last(String.format(" order by %s %s", cinemaQueryListBO.getOrderCol(), cinemaQueryListBO.getOrderDir()));

        // 处理电影院数据

        Page<Cinema> page = new Page<>(cinemaQueryListBO.getCurrentIndex(), cinemaQueryListBO.getPageSize());
        List<Cinema> cinemaList = cinemaMapper.selectPage(page, cinemaLambdaQueryWrapper).getRecords();

        List<CinemaSpecial> cinemaSpecialList = new ArrayList<>();
        Map<Integer, List<CinemaSpecial>> csMap = new HashMap<>();
        // 处理电影院列表中电影的特殊服务json字符串
        for(var c : cinemaList){
            // 逻辑问题
            csMap.put(c.getCmaId(), JsonUtil.decodeJsonToList(c.getCmaSepcial(), CinemaSpecial.class));
        }

        cinemaQueryListBO.setTotalRecord(page.getTotal());
        cinemaQueryListBO.setTotalPage((int)page.getPages());

        // 存放电影院列表
        cinemaQueryListDTO.setCinemas(cinemaList);
        // 存放电影院的特别列表
        cinemaQueryListDTO.setCinemaSpecials(csMap);
        cinemaQueryListDTO.setBo(cinemaQueryListBO);


        return cinemaQueryListDTO;
    }

    @Override
    public CinemaQueryModelDTO CinemaQueryModel(Integer cmaId) {
        CinemaQueryModelDTO cinemaQueryModelDTO = new CinemaQueryModelDTO();

        // 加载电影院的实体信息
        Cinema cinema = cinemaMapper.selectById(cmaId);
        // 处理电影院中的服务JSON字符串
        cinemaQueryModelDTO.setCinemaServices(JsonUtil.decodeJsonToList(cinema.getCmaService(), org.bwf.study.model.CinemaService.class));
        cinemaQueryModelDTO.setCinema(cinema);

        // 加载影院中的电影信息
        LambdaQueryWrapper<CinemaFilmRel> cinemaFilmRelLambdaQueryWrapper = Wrappers.lambdaQuery();
        cinemaFilmRelLambdaQueryWrapper.eq(CinemaFilmRel::getCmaId, cmaId);
        // 加载影院和影片的关系列表
        List<CinemaFilmRel> cinemaFilmRelList = cinemaFilmRelMapper.selectList(cinemaFilmRelLambdaQueryWrapper);
        // 如果影院和影片的关系是零，代表没有任何影片和场次，直接返回dto中影院信息
        if(cinemaFilmRelList.size() <= 0) return cinemaQueryModelDTO;
        // 遍历集合，填充电影ID集合
        List<Integer> filmIds = new ArrayList<>();
        for(var cf : cinemaFilmRelList){
            filmIds.add(cf.getFilmId());
        }
        LambdaQueryWrapper<Film> filmLambdaQueryWrapper = Wrappers.lambdaQuery();
        filmLambdaQueryWrapper.in(Film::getFilmId, filmIds);
        List<Film> filmList = filmMapper.selectList(filmLambdaQueryWrapper);

        // 加载场次信息
        LambdaQueryWrapper<WatchTimes> watchTimesLambdaQueryWrapper = Wrappers.lambdaQuery();
        // 需要根据电影ID和影院ID去查询，相关影院相关影片的所有场次
        watchTimesLambdaQueryWrapper.in(WatchTimes::getFilmId, filmIds).eq(WatchTimes::getCmaId, cmaId);
        List<WatchTimes> watchTimesList = watchTimesMapper.selectList(watchTimesLambdaQueryWrapper);

        // 处理Film列表中的 演职人员的JSON字符串
        // 处理影片和场次的相关联系数据
        Map<Integer, List<FilmActor>> faMap = new HashMap<>();
        Map<Integer, List<WatchTimes>> wtMap = new HashMap<>();
        for(var f : filmList){
            faMap.put(f.getFilmId(), JsonUtil.decodeJsonToList(f.getFilmActors(), FilmActor.class));
            // 使用filter函数来进行数据筛选，参数是lambda表达式
            wtMap.put(f.getFilmId(), watchTimesList.stream().
                    filter(watch -> watch.getFilmId().equals(f.getFilmId())).collect(Collectors.toList()));
        }

        cinemaQueryModelDTO.setFilms(filmList);
        cinemaQueryModelDTO.setFilmActors(faMap);
        cinemaQueryModelDTO.setWatchTimes(wtMap);

        return cinemaQueryModelDTO;
    }


}
